#ifndef __WIZ_BNF_POLICIES_HPP__SHANHAOBO_19800429__
#define __WIZ_BNF_POLICIES_HPP__SHANHAOBO_19800429__

#include <xutility>

#include "../Base/WizBase.hpp"
#include "./WizBNFID.hpp"

namespace Wiz
{
    namespace BNF
    {
        namespace Policy
        {
            //////////////////////////////////////////////////////////////////////////
            /// 
            /// Iteration 
            /// 
            //////////////////////////////////////////////////////////////////////////
            struct Iteration
            {
                template <typename ScannerT>
                ::Wiz::Void::Type Advance(ScannerT const& Scan) const
                {
                    ++(Scan.m_Curr);
                }

                template <typename ScannerT>
                ::Wiz::Bool::Type AtEnd(ScannerT const& Scan) const
                {
                    return Scan.m_Curr == Scan.m_Last;
                }

                template <typename T>
                T Filter(T Chr) const
                {
                    return Chr;
                }

                template <typename ScannerT>
                typename ScannerT::tReference Get(ScannerT const& Scan) const
                {
                    return *(Scan.m_Curr);
                }
            };

            //////////////////////////////////////////////////////////////////////////
            /// 
            /// Match 
            /// 
            //////////////////////////////////////////////////////////////////////////
            struct Match
            {
                template <typename T>
                struct Result
                {
                    typedef ::Wiz::BNF::Match::Type<T> tType;
                };

                /// Failed Match
                const ::Wiz::BNF::Match::Type<::Wiz::Null::Type>
                NoMatch() const
                {
                    return ::Wiz::BNF::Match::Type<::Wiz::Null::Type>();
                }

                /// Empty Match But Successed
                const ::Wiz::BNF::Match::Type<::Wiz::Null::Type>
                EmptyMatch() const
                {
                    return ::Wiz::BNF::Match::Type<::Wiz::Null::Type>(0, ::Wiz::Null::Type());
                }

                template <typename AttributeT, typename IteratorT>
                ::Wiz::BNF::Match::Type<AttributeT>
                CreateMatch
                (
                    ::Wiz::Size::In     Length,
                    AttributeT const&   Value,
                    IteratorT const&    WIZ_UNUSED(Curr),
                    IteratorT const&    WIZ_UNUSED(Last)
                ) const
                {
                    return ::Wiz::BNF::Match::Type<AttributeT>(Length, Value);
                }

                template <typename Match1T, typename Match2T>
                ::Wiz::Void::Type ConcatMatch(Match1T& Lft, Match2T const& Rght) const
                {
                    Lft.Concat(Rght);
                }

                template <typename MatchT, typename IteratorT>
                ::Wiz::Void::Type GroupMatch
                (
                    MatchT&             WIZ_UNUSED(Mtch),
                    ::Wiz::BNF::ID::In  WIZ_UNUSED(Id),
                    IteratorT const&    WIZ_UNUSED(Frst),
                    IteratorT const&    WIZ_UNUSED(Lst)
                ) const
                {}
            };

            //////////////////////////////////////////////////////////////////////////
            /// 
            /// Action 
            /// 
            //////////////////////////////////////////////////////////////////////////
            struct Action
            {
                template <typename AttributeT>
                struct ActionAttributed
                {
                    template <typename ActorT, typename IteratorT>
                    static ::Wiz::Void::Type Call
                    (
                        ActorT const&       Actor,
                        AttributeT&         Value,
                        IteratorT const&    WIZ_UNUSED(Curr),
                        IteratorT const&    WIZ_UNUSED(Last)
                    )
                    {
                        Actor(Value);
                    }
                };

                template <>
                struct ActionAttributed<::Wiz::Null::Type>
                {
                    template <typename ActorT, typename IteratorT>
                    static ::Wiz::Void::Type Call
                    (
                        ActorT const&       Actor,
                        ::Wiz::Null::Type   WIZ_UNUSED(Value),
                        IteratorT const&    Curr,
                        IteratorT const&    Last
                    )
                    {
                        Actor(Curr, Last);
                    }
                };

                template <typename ActorT, typename AttributeT, typename IteratorT>
                ::Wiz::Void::Type DoAction
                    (
                    ActorT const&       Actor,
                    AttributeT&         Value,
                    IteratorT const&    Curr,
                    IteratorT const&    Last
                    ) const
                {
                    ActionAttributed<AttributeT>::Call(Actor, Value, Curr, Last);
                }
            };

            //////////////////////////////////////////////////////////////////////////
            /// 
            /// Scanner 
            /// 
            //////////////////////////////////////////////////////////////////////////
            template
            <
                typename IterationPolicyT   = ::Wiz::BNF::Policy::Iteration,
                typename MatchPolicyT       = ::Wiz::BNF::Policy::Match,
                typename ActionPolicyT      = ::Wiz::BNF::Policy::Action
            >
            struct Scanner : public IterationPolicyT,  public MatchPolicyT, public ActionPolicyT
            {
                typedef IterationPolicyT    tIterationPolicy;
                typedef MatchPolicyT        tMatchPolicy;
                typedef ActionPolicyT       tActionPolicy;

                Scanner
                (
                    IterationPolicyT const& i_policy = IterationPolicyT(),
                    MatchPolicyT const&     m_policy = MatchPolicyT(),
                    ActionPolicyT const&    a_policy = ActionPolicyT()
                ) : IterationPolicyT(i_policy), MatchPolicyT(m_policy), ActionPolicyT(a_policy)
                {}

                template <typename ScannerPoliciesT>
                Scanner(ScannerPoliciesT const& Policies) : IterationPolicyT(Policies), MatchPolicyT(Policies), ActionPolicyT(Policies)
                {}
            };

            namespace Skipper
            {
                namespace Iteration
                {
                    ///////////////////////////////////////////////////////////////////////////
                    //
                    //  Type class
                    //
                    ///////////////////////////////////////////////////////////////////////////
                    template <typename BaseT = ::Wiz::BNF::Policy::Iteration>
                    struct Type : public BaseT
                    {
                        typedef BaseT tSuper;

                        Type() : tSuper()
                        {}

                        template <typename PolicyT>
                        Type(PolicyT const& Other) : tSuper(Other)
                        {}

                        template <typename ScannerT>
                        ::Wiz::Void::Type Advance(ScannerT const& Scan) const
                        {
                            tSuper::Advance(Scan);
                            Scan.Skip(Scan);
                        }

                        template <typename ScannerT>
                        ::Wiz::Bool::Type AtEnd(ScannerT const& Scan) const
                        {
                            Scan.Skip(Scan);
                            return tSuper::AtEnd(Scan);
                        }

                        template <typename ScannerT>
                        ::Wiz::Void::Type Skip(ScannerT const& Scan) const
                        {
                            while (!tSuper::AtEnd(Scan) && ::Wiz::IsSpace(tSuper::Get(Scan)))
                            {
                                tSuper::Advance(Scan);
                            }
                        }
                    };

                    namespace Parser
                    {
                        template <typename ParserT, typename BaseT = ::Wiz::BNF::Policy::Iteration>
                        class Type : public ::Wiz::BNF::Policy::Skipper::Iteration::Type<BaseT>
                        {
                        public:
                            typedef ::Wiz::BNF::Policy::Skipper::Iteration::Type<BaseT> tSuper;

                            Type
                            (
                                ParserT const& SkpPrsr,
                                tSuper const& Base      = tSuper()
                            ) : tSuper(Base), m_Subject(SkpPrsr)
                            {}

                            template <typename PolicyT>
                            Type(PolicyT const& Other) : tSuper(Other), m_Subject(Other.Skipper())
                            {}

                            template <typename ScannerT>
                            ::Wiz::Void::Type Skip(ScannerT const& Scan) const
                            {
                                ::Wiz::BNF::Skipper::Skip(m_Subject, Scan, Scan);
                            }

                            ParserT const& Skipper() const
                            { 
                                return m_Subject; 
                            }

                        private:
                            ParserT const& m_Subject;
                        };
                    } /// end of namespace Parser
                } /// end of namespace Iteration

                namespace Scanner
                {
                    typedef ::Wiz::BNF::Policy::Skipper::Iteration::Type<::Wiz::BNF::Policy::Iteration> tIteration;
                    typedef ::Wiz::BNF::Policy::Scanner<tIteration>                                     Type;
                } /// end of namespace Scanner
            } /// end of namespace Skipper

            namespace NoSkipper
            {
                namespace Iteration
                {
                    ///////////////////////////////////////////////////////////////////////////
                    //
                    //  no_skipper_iteration_policy class
                    //
                    ///////////////////////////////////////////////////////////////////////////
                    template <typename BaseT = ::Wiz::BNF::Policy::Iteration>
                    struct Type : public BaseT
                    {
                        typedef BaseT tSuper;

                        Type() : tSuper() {}

                        template <typename PolicyT>
                        Type(PolicyT const& Other) : tSuper(Other)
                        {}

                        template <typename ScannerT>
                        ::Wiz::Void::Type Skip(ScannerT const& WIZ_UNUSED(Scan)) const
                        {}
                    };
                } /// end of namespace Iteration
            } /// end of namespace NoSkipper
        } /// end of namespace Policy
    } /// end of namespace BNF
} /// end of namespace Wiz

#endif /*__WIZ_BNF_POLICIES_HPP__SHANHAOBO_19800429__*/
